treeviewcolumn: Redo sort arrows
authorMatthias Clasen <mclasen@redhat.com>
Mon, 18 Jan 2021 21:11:57 +0000 (16:11 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 19 Jan 2021 19:02:16 +0000 (14:02 -0500)
Instead of hardcoding icon names in the widget, use
sort-indicator.ascending and sort-indicator.descending styles
and set the icon to use with -gtk-icon-source. This lets themes
change the icon that is used here, without forcing all uses of
pan-up/down-symbolic to be treated the same.

Document this in the treeview CSS docs.

Fixes: #3577
gtk/gtktreeview.c
gtk/gtktreeviewcolumn.c
gtk/theme/Adwaita/_common.scss

index 82d5fd97d87225f813c70d35ac3416900d9b8cdb..267c90b4faeeda011d8a3d05fb32fab33c566449 100644 (file)
  * |[<!-- language="plain" -->
  * treeview.view
  * ├── header
- * │   ├── <column header>
+ * │   ├── button
+ * │   │   ╰── [sort-indicator]
  * ┊   ┊
- * │   ╰── <column header>
+ * │   ╰── button
+ * │       ╰── [sort-indicator]
  * │
  * ├── [rubberband]
  * ╰── [dndtarget]
  * It has a subnode with name header, which is the parent for all the column
  * header widgets' CSS nodes.
  *
+ * Each column header consists of a button, which among other content, has a
+ * child with name sort-indicator, which carries the .ascending or .descending
+ * style classes when the column header should show a sort indicator. The CSS
+ * is expected to provide a suitable image using the -gtk-icon-source property.
+ *
  * For rubberband selection, a subnode with name rubberband is used.
  *
  * For the drop target location during DND, a subnode with name dndtarget is used.
index e321bed4b67b65ef4a809809fe262b4c0fa2ef3c..d546c994f275af7fc52afd1f7a3482cd77f97ac7 100644 (file)
@@ -38,6 +38,7 @@
 #include "gtkgesturedrag.h"
 #include "gtkeventcontrollerfocus.h"
 #include "gtkeventcontrollerkey.h"
+#include "gtkbuiltiniconprivate.h"
 
 #include <string.h>
 
  *   [GtkTreeView drag-and-drop][gtk3-GtkTreeView-drag-and-drop]
  *
  * The GtkTreeViewColumn object represents a visible column in a #GtkTreeView widget.
- * It allows to set properties of the column header, and functions as a holding pen for
- * the cell renderers which determine how the data in the column is displayed.
+ * It allows to set properties of the column header, and functions as a holding pen
+ * for the cell renderers which determine how the data in the column is displayed.
  *
  * Please refer to the [tree widget conceptual overview][TreeWidget]
- * for an overview of all the objects and data types related to the tree widget and how
- * they work together.
+ * for an overview of all the objects and data types related to the tree widget and
+ * how they work together, and to the #GtkTreeView documentation for specifics about
+ * the CSS node structure for treeviews and their headers.
  */
 
 
@@ -879,7 +881,7 @@ gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
   gtk_widget_set_halign (priv->frame, GTK_ALIGN_START);
 
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
-  priv->arrow = gtk_image_new_from_icon_name ("pan-down-symbolic");
+  priv->arrow = gtk_builtin_icon_new ("sort-indicator");
 
   if (priv->child)
     child = priv->child;
@@ -905,7 +907,7 @@ gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
   gtk_button_set_child (GTK_BUTTON (priv->button), hbox);
 }
 
-static void 
+static void
 gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
 {
   GtkTreeViewColumnPrivate *priv = tree_column->priv;
@@ -914,7 +916,6 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
   GtkWidget *frame;
   GtkWidget *arrow;
   GtkWidget *current_child;
-  const char *icon_name = "missing-image";
   GtkTreeModel *model;
 
   if (priv->tree_view)
@@ -948,17 +949,17 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
       g_return_if_fail (GTK_IS_LABEL (current_child));
 
       if (priv->title)
-       gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
-                                         priv->title);
+        gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
+                                          priv->title);
       else
-       gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
-                                         "");
+        gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
+                                          "");
     }
 
   if (GTK_IS_TREE_SORTABLE (model))
     gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
-                                         &sort_column_id,
-                                         NULL);
+                                          &sort_column_id,
+                                          NULL);
 
   if (priv->show_sort_indicator)
     {
@@ -971,24 +972,19 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
       else
         alternative = FALSE;
 
-      switch (priv->sort_order)
+      if ((!alternative && priv->sort_order == GTK_SORT_ASCENDING) ||
+          (alternative && priv->sort_order == GTK_SORT_DESCENDING))
         {
-         case GTK_SORT_ASCENDING:
-            icon_name = alternative ? "pan-up-symbolic" : "pan-down-symbolic";
-           break;
-
-         case GTK_SORT_DESCENDING:
-            icon_name = alternative ? "pan-down-symbolic" : "pan-up-symbolic";
-           break;
-
-         default:
-           g_warning (G_STRLOC": bad sort order");
-           break;
-       }
+          gtk_widget_remove_css_class (arrow, "descending");
+          gtk_widget_add_css_class (arrow, "ascending");
+        }
+      else
+        {
+          gtk_widget_remove_css_class (arrow, "ascending");
+          gtk_widget_add_css_class (arrow, "descending");
+        }
     }
 
-  gtk_image_set_from_icon_name (GTK_IMAGE (arrow), icon_name);
-
   /* Put arrow on the right if the text is left-or-center justified, and on the
    * left otherwise; do this by packing boxes, so flipping text direction will
    * reverse things
index b5094c68e61b63ffc13830dff9ca06ca0a8302a8..58d50a1dbecff48a0726b80b89814a323be919ac 100644 (file)
@@ -1766,6 +1766,17 @@ treeview.view {
         color: $fg_color;
         transition: none; //I shouldn't need this
       }
+      sort-indicator {
+        &.ascending {
+          -gtk-icon-source: -gtk-icontheme('pan-up-symbolic');
+        }
+        &.descending {
+          -gtk-icon-source: -gtk-icontheme('pan-down-symbolic');
+        }
+
+        min-height: 16px;
+        min-width: 16px;
+      }
     }
   }